#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"
#include "historydialog.h"
#include "smtp\SmtpMime.h"

#include "version.h"
#include "windows.h"

#include <QtGui>
#include <QtSql>

#include <QDebug>
#include <QMessageBox>
#include <QtAddOnSerialPort/serialportinfo.h>
#include <QtCore/qmath.h>
#include <QDir>
#include <QSettings>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setSystemTrayIcon();

    this->alarmState = MainWindow::AlarmOff;
    this->mail_ready = true;

    this->transactionCount = 0;
    this->currentTemperature = 0;
    this->deltaCount = 0;

    QChar ch(0x00B0);

    ui->data_groupBox->setTitle(tr("Temperature (%1C)").arg(ch));

    this->setupPorts();

    this->cpu_time = 0;

    ui->data_textEdit->document()->setMaximumBlockCount(50);

    this->readSettings();

    ui->lcdNumber->display("?");

    ui->plot->addGraph();

    this->setupGraph();

    connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(exitApplication()));
    connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
    connect(ui->run_pushButton, SIGNAL(clicked()), this, SLOT(transaction()));
    connect(ui->actionSettings, SIGNAL(triggered()), this, SLOT(editSettings()));
    connect(&thread, SIGNAL(response(QString)), this, SLOT(showResponse(QString)));
    connect(&thread, SIGNAL(error(QString)), this, SLOT(processError(QString)));
    connect(&thread, SIGNAL(timeout(QString)), this, SLOT(processTimeout(QString)));
    connect(&thread, SIGNAL(rdtsime(long long)), this, SLOT(rdtsime(long long)));
    connect(&thread, SIGNAL(cputime(long long)), this, SLOT(cputime(long long)));
    connect(&thread, SIGNAL(finished()), this, SLOT(finished()));
    connect(&thread, SIGNAL(terminated()), this, SLOT(terminated()));

    if(qApp->property("auto_updates").toBool()) this->updateProgram();

    if(qApp->property("autorun").toBool()){
        if(qApp->property("delay_run").toInt() > 0){
            QTimer::singleShot(qApp->property("delay_run").toInt()*1000, this, SLOT(transaction()));
        }
        else this->transaction();
    }

    this->setupDatabase();
}

MainWindow::~MainWindow()
{
    this->saveSettings();
    delete ui;
}

void MainWindow::setupPorts()
{
    QList<QtAddOn::SerialPort::SerialPortInfo> list = QtAddOn::SerialPort::SerialPortInfo::availablePorts();

    foreach (const QtAddOn::SerialPort::SerialPortInfo &info, list) {
        QString s = info.portName();
        ui->ports_comboBox->addItem(s);
    }
}

void MainWindow::about()
{
    QString msg(tr("Version: %1\nAuthor: Venelin Georgiev\nPleven, Bulgaria\nE-mail: veni_georgiev@mail.bg")
            .arg(_STR_PRODUCT_VERSION));
    QMessageBox::about( this, tr("About SerialTemper"), msg) ;
}

void MainWindow::transaction()
{
    if(thread.isRunning()){
        thread.stop();
        //setControlsEnabled(true);
        return;
    }
    setControlsEnabled(false);
    thread.transaction(ui->ports_comboBox->currentText(),
                       ui->checkout_spinBox->value());
    ui->data_textEdit->append(tr("Status: Running, connected to port %1.")
                         .arg(ui->ports_comboBox->currentText()));
    setControlsEnabled(false);
}

void MainWindow::showResponse(const QString &s)
{
    //setControlsEnabled(true);
    ui->data_textEdit->append(tr("Traffic, transaction #%1:"
                             "\n\r-response: %2")
                          .arg(++transactionCount).arg(s));
}

void MainWindow::processError(const QString &s)
{
    //setControlsEnabled(true);
    ui->data_textEdit->append(tr("Status: Not running, %1.").arg(s));
    ui->data_textEdit->append(tr("No traffic."));
}

void MainWindow::processTimeout(const QString &s)
{
    //setControlsEnabled(true);
    ui->data_textEdit->append(tr("Status: Running, %1.").arg(s));
    ui->data_textEdit->append(tr("No traffic."));
}

void MainWindow::rdtsime(const long long t)
{
    /*
     *temp:=a*1/ln(us)+b;
     *
    */
    int a = qApp->property("a_constant").toInt();
    int b = qApp->property("b_constant").toInt();

    double us = double(t)/double(this->cpu_time);
    double _temp = a*1/qLn(us)+b;

    if(this->setTemperature(_temp)){
        uint _time = QDateTime::currentDateTime().toTime_t();

        ui->plot->graph()->removeDataBefore(_time - qApp->property("graphics_history").toInt()*24*60*60);

        ui->plot->graph()->addData(_time, _temp);


        if(ui->plot->xAxis->range().contains(_time)){
            ui->plot->xAxis->setRange(_time-500, _time+100);
            ui->plot->replot();
        }

        ui->lcdNumber->display(QString::number(this->currentTemperature, 'f', 2));

        if(qApp->property("save_history").toBool()){//save values in database
            QSqlQuery* query = new QSqlQuery(QSqlDatabase::database());
            QString q = QString("INSERT INTO `history` (`datetime`,`temp`)"
                                        "VALUES('%1','%2')")
                                .arg(_time)
                                .arg(_temp);

            if(!query->exec(q)){
                ui->data_textEdit->append(tr("Sql error: %1").arg(query->lastError().text()));
            }
        }
        if(qApp->property("alarm").toBool()){
            if(qApp->property("min_temp").toInt() <= this->currentTemperature
                    && this->currentTemperature <= qApp->property("max_temp").toInt()){
                //normal temp
                if(this->alarmState == MainWindow::AlarmOn){
                //temperature return to normal limit
                    this->setAlarm(false);
                }
            }
            else{
                if(this->alarmState == MainWindow::AlarmOff){
                    if(this->currentTemperature < qApp->property("min_temp").toInt()){
                        this->alarmType = MainWindow::AlarmLow;
                    }
                    else{
                        this->alarmType = MainWindow::AlarmHigh;
                    }
                }
                this->setAlarm(true);
                this->sendMail();
            }
        }
    }

    if(!ui->detailed_checkBox->isChecked()){
        QChar ch(0x00B0);
        ui->data_textEdit->append(tr("%1 - %2 %3C")
                                  .arg(QDateTime::currentDateTime().toString("dd:MM:yyyy HH:mm"))
                                  .arg(QString::number(_temp, 'f', 2))
                                  .arg(ch)
                                  );
    }
    else {
        ui->data_textEdit->append(tr("Current measurements:\ntime: %1 (microseconds)\n"
                                 "cpuspeed: %2 Mhz\n"
                                 "us: %3 (time/cpuspeed)\n"
                                 "a: %4 (a constant)\n"
                                 "b: %5 (b constant)\n"
                                 "Log(us): %6\n"
                                 "temp: %7 C (a*1/Log(us)+b)")
                              .arg(t)
                              .arg(this->cpu_time)
                              .arg(us)
                              .arg(a)
                              .arg(b)
                              .arg(qLn(us))
                              .arg(QString::number(_temp, 'f', 2))
                              );
    }
}

void MainWindow::cputime(const long long time)
{
    this->cpu_time = time;
    //qDebug() << "Current cpu time: " << time;
    //ui->data_textEdit->append(tr("Current cpu speed: %1 Mhz").arg(time));
}

void MainWindow::finished()
{
    //qDebug() << "Thread finished";
    setControlsEnabled(true);
}

void MainWindow::terminated()
{
    //qDebug() << "Thread terminated";
    setControlsEnabled(true);
}

void MainWindow::setControlsEnabled(bool enable)
{
    ui->settings_groupBox->setEnabled(enable);
    ui->run_pushButton->setText(enable ? tr("Run") : tr("Stop"));
    ui->run_pushButton->setIcon(enable ? QIcon(":/icons/icons/Play.png") : QIcon(":/icons/icons/Stop.png"));
}

void MainWindow::readSettings()
 {
   // QDir appdir = qApp->applicationDirPath();
    QDir appdir = QDir::home();
    QSettings settings(appdir.filePath("SerialTemper.ini"), QSettings::IniFormat);
    settings.beginGroup("Program");
        restoreGeometry(settings.value("Geometry").toByteArray());
        restoreState(settings.value("State").toByteArray());
        ui->splitter->restoreState(settings.value("SplitterSizes").toByteArray());
        ui->plot_splitter->restoreState(settings.value("PlotSplitterSizes").toByteArray());
        qApp->setProperty("autostart", settings.value("Autostart", false).toBool());
        qApp->setProperty("autorun", settings.value("Autorun", false).toBool());
        qApp->setProperty("delay_run", settings.value("DelayRun", 0).toInt());
        qApp->setProperty("auto_updates", settings.value("AutoUpdates", true).toBool());
    settings.endGroup();
    settings.beginGroup("Interface");
        qApp->setProperty("hide_close_message", settings.value("HideCloseMessage", false).toBool());
        qApp->setProperty("minimized", settings.value("Minimized", false).toBool());
    settings.endGroup();
    settings.beginGroup("Settings");
        QString port = settings.value("Portname", "COM1").toString();
        qApp->setProperty("a_constant", settings.value("AConstant", 0).toInt());
        qApp->setProperty("b_constant", settings.value("BConstant", 0).toInt());
        qApp->setProperty("delta", settings.value("Delta", 1).toDouble());
        qApp->setProperty("attempts", settings.value("Attempts", 3).toInt());
        qApp->setProperty("alarm", settings.value("Alarm", false).toBool());
        qApp->setProperty("max_temp", settings.value("MaxTemp", 30).toInt());
        qApp->setProperty("min_temp", settings.value("MinTemp", 0).toInt());
        qApp->setProperty("check_interval", settings.value("CheckInterval", 10).toInt());

        int check_interval = qApp->property("check_interval").toInt();
        bool detail_log = settings.value("DetailLog", false).toBool();
    settings.endGroup();
    settings.beginGroup("SMTP");
        qApp->setProperty("smtp_type", settings.value("SmtpType").toString());
        qApp->setProperty("smtp_server", settings.value("SmtpServer").toString());
        qApp->setProperty("smtp_port", settings.value("SmtpPort").toString());
        qApp->setProperty("smtp_user", settings.value("SmtpUser").toString());
        qApp->setProperty("smtp_pass", QByteArray::fromBase64(settings.value("SmtpPass").toByteArray()).data());
        qApp->setProperty("smtp_sender", settings.value("SmtpSender").toString());
        qApp->setProperty("smtp_subject", settings.value("SmtpSubject").toString());
        qApp->setProperty("smtp_recipients", settings.value("SmtpRecipients").toStringList());
        qApp->setProperty("smtp_interval", settings.value("SmtpInterval", 10).toInt());
        qApp->setProperty("smtp_workstation", settings.value("Workstation").toString());
    settings.endGroup();
    settings.beginGroup("Graphics");
        qApp->setProperty("graphics_show", settings.value("GraphicsShow", false).toBool());
        qApp->setProperty("graphics_step", settings.value("GraphicsStep", 1).toInt());
        qApp->setProperty("graphics_history", settings.value("GraphicsHistory", 3).toInt());
    settings.endGroup();
    settings.beginGroup("Database");
        qApp->setProperty("save_history", settings.value("SaveHistory").toBool());
    settings.endGroup();

    ui->ports_comboBox->setCurrentIndex(ui->ports_comboBox->findText(port));
    ui->checkout_spinBox->setValue(check_interval);
    ui->detailed_checkBox->setChecked(detail_log);
 }

void MainWindow::saveSettings()
{
    //QDir appdir = qApp->applicationDirPath();
    QDir appdir = QDir::home();
    QSettings settings(appdir.filePath("SerialTemper.ini"), QSettings::IniFormat);
    settings.beginGroup("Program");
    settings.setValue("Geometry", saveGeometry());
    settings.setValue("State", saveState());
    settings.setValue("SplitterSizes", ui->splitter->saveState());
    settings.setValue("PlotSplitterSizes", ui->plot_splitter->saveState());
    settings.endGroup();
    settings.beginGroup("Interface");
    settings.endGroup();
    settings.beginGroup("Settings");
    settings.setValue("Portname", ui->ports_comboBox->currentText());
    //settings.setValue("AConstant", qApp->property("a_constant").toInt());
    //settings.setValue("BConstant", qApp->property("b_constant").toInt());
    settings.setValue("CheckInterval", ui->checkout_spinBox->value());
    settings.setValue("DetailLog", ui->detailed_checkBox->isChecked());
    //settings.setValue("Alarm", qApp->property("alarm").toBool());
    //settings.setValue("MaxTemp", qApp->property("max_temp").toInt());
    //settings.setValue("MinTemp", qApp->property("min_temp").toInt());
    settings.endGroup();
}

void MainWindow::exitApplication()
{
    thread.stop();
    //thread.terminate();
    qApp->quit();
}

bool MainWindow::hasMinimizedStartup()
{
    //QDir appdir = qApp->applicationDirPath();
    QDir appdir = QDir::home();
    QSettings settings(appdir.filePath("SerialTemper.ini"), QSettings::IniFormat);
    settings.beginGroup("Interface");
    bool minimize = settings.value("Minimized", false).toBool();
    settings.endGroup();
    return minimize;
}

void MainWindow::onOtherInstanceMessage(const QString &msg)
{
    qDebug() << msg;
    if(this->isHidden()) this->show();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible() && !isHidden()) {
        /*QErrorMessage* msg = QErrorMessage::qtHandler();
        msg->showMessage( tr("The program will keep running in the "
                             "system tray. To terminate the program, "
                             "choose <b>Quit</b> in the context menu "
                             "of the system tray entry."), "Systray");
                             */
        if(!qApp->property("hide_close_message").toBool()){
            QMessageBox msgBox;
            msgBox.setText(tr("The program will keep running in the "
                              "system tray. To terminate the program, "
                              "choose <b>Quit</b> in the context menu "
                              "of the system tray entry."));
            QCheckBox* show_checkBox = new QCheckBox(tr("Disable this message"), &msgBox);
            QLayout* layout = msgBox.layout();
            layout->addWidget(show_checkBox);

            msgBox.exec();

            //QDir appdir = qApp->applicationDirPath();
            QDir appdir = QDir::home();
            QSettings settings(appdir.filePath("SerialTemper.ini"), QSettings::IniFormat);
            settings.beginGroup("Interface");
            {
                settings.setValue("HideCloseMessage", show_checkBox->isChecked());
            }
            settings.endGroup();
            qApp->setProperty("hide_close_message", show_checkBox->isChecked());
        }

        this->hide();
        event->ignore();
    }
    else{
        event->accept();
    }
}

void MainWindow::setSystemTrayIcon()
{
    if(!QSystemTrayIcon::isSystemTrayAvailable() ){
        return;
    }
    this->createTrayActions();

    trayIconMenu = new QMenu(this);

    trayIconMenu->addAction(minimizeAction);
    trayIconMenu->addAction(restoreAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(ui->actionExit);

    trayIcon = new QSystemTrayIcon(this->windowIcon(), this);


    trayIcon->setContextMenu(trayIconMenu);

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(systemTrayActivation(QSystemTrayIcon::ActivationReason)));

    trayIcon->show();
}

void MainWindow::createTrayActions()
{
    minimizeAction = new QAction(QIcon(":/icons/icons/Minimize.png"), tr("Mi&nimize"), this);
    connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));

    restoreAction = new QAction(QIcon(":/icons/icons/Restore.png"), tr("&Restore"), this);
    connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
}

void MainWindow::systemTrayActivation(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
        case QSystemTrayIcon::Trigger:
        case QSystemTrayIcon::DoubleClick:
        case QSystemTrayIcon::MiddleClick:
        {
            if(this->isMinimized()){
                this->showNormal();
                this->activateWindow();
                break;
            }
            if(this->isHidden()){
                this->show();
                this->activateWindow();
                break;
            }
            else{
                this->hide();
                break;
            }
        }
            default: return;
        }
}

void MainWindow::editSettings()
{
    SettingsDialog* dlg = new SettingsDialog(this);
    if(dlg->exec() == QDialog::Accepted){
        this->setupGraph();
    }
    delete dlg;
}

bool MainWindow::setTemperature(double temp)
{
    double delta = qApp->property("delta").toDouble();
    if(abs(this->currentTemperature - temp) <= delta){
        this->currentTemperature = temp;
        this->deltaCount = 0;
        return true;
    }
    else{
        if(ui->detailed_checkBox->isChecked()){
            ui->data_textEdit->append(tr("Measured is a great difference!\nOld - %1, new - %2! Delta count: %3")
                                      .arg(this->currentTemperature)
                                      .arg(QString::number(temp, 'f', 2))
                                      .arg(this->deltaCount)
                                      );
        }
        if(deltaCount >= (qApp->property("attempts").toInt()-1) && abs(this->deltaTemperature - temp) <= delta){
            this->currentTemperature = temp;
            this->deltaCount = 0;
            return true;
        }
        else{
            this->deltaTemperature = temp;
            this->deltaCount++;
        }
    }
    return false;
}

void MainWindow::setAlarm(bool set)
{
    this->alarmState = (set ? MainWindow::AlarmOn : MainWindow::AlarmOff);
    if(!set){
        ui->lcdNumber->setPalette(this->palette());
        ui->data_textEdit->append(tr("Switched alarm state in Alarm Off"));
    }
    else{
        QPalette palette(this->palette());
        palette.setColor(QPalette::WindowText, this->alarmType == MainWindow::AlarmHigh ? Qt::red : Qt::blue);
        ui->lcdNumber->setPalette(palette);
        ui->data_textEdit->append(tr("Switched alarm state in Alarm On"));
    }
}

void MainWindow::sendMail()
{
    if(this->last_msg.isValid() && last_msg.secsTo(QDateTime::currentDateTime()) < (qApp->property("smtp_interval").toInt()*60)){
        if(ui->detailed_checkBox->isChecked()){
            ui->data_textEdit->append(tr("%1 - The time between messages is too short. Break operation...")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      );
        }
        return;
    }
    if(!this->mail_ready) return;
    this->mail_ready = false;
    SmtpClient* smtp = new SmtpClient();
    MimeMessage* message = new MimeMessage();
    MimeText* text = new MimeText();
    QChar ch(0x00B0);
    QString host(qApp->property("smtp_server").toString());
    if(qApp->property("smtp_type").toString() == "Gmail"){
        smtp->setHost(host);
        //smtp->setPort(465);
        smtp->setPort(qApp->property("smtp_port").toInt());
        smtp->setConnectionType(SmtpClient::SslConnection);
        smtp->setUser(qApp->property("smtp_user").toString());
        smtp->setPassword(qApp->property("smtp_pass").toString());
        message->setSender(new EmailAddress(qApp->property("smtp_user").toString(), qApp->property("smtp_sender").toString()));
        QStringList list = qApp->property("smtp_recipients").toStringList();
        foreach (const QString &str, list) {
            message->addRecipient(new EmailAddress(str, str));
        }
        if(smtp->connectToHost()) smtp->login();
        else{
            if(ui->detailed_checkBox->isChecked()){
                ui->data_textEdit->append(tr("%1 - Error connect to SMTP host: %2")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      .arg(smtp->getSocket()->errorString())
                                      );
            }
            delete(smtp);
            delete(message);
            delete(text);
            this->mail_ready = true;
            return;
        }
    }
    else if (qApp->property("smtp_type").toString() == "SMTP without login"){
        smtp->setHost(host);
        smtp->setPort(qApp->property("smtp_port").toInt());
        //smtp->setPort(25);
        smtp->setConnectionType(SmtpClient::TcpConnection);
        message->setSender(new EmailAddress(qApp->property("smtp_sender").toString(), qApp->property("smtp_sender").toString()));
        QStringList list = qApp->property("smtp_recipients").toStringList();
        foreach (const QString &str, list) {
            message->addRecipient(new EmailAddress(str, str));
        }
        if(!smtp->connectToHost()){
            if(ui->detailed_checkBox->isChecked()){
                ui->data_textEdit->append(tr("%1 - Error connect to SMTP host: %2")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      .arg(smtp->getSocket()->errorString())
                                      );
            }
            this->mail_ready = true;
            delete(smtp);
            delete(message);
            delete(text);
            return;
        }
    }
    else if (qApp->property("smtp_type").toString() == "SMTP with login"){
        smtp->setHost(host);
        //smtp->setPort(465);
        smtp->setPort(qApp->property("smtp_port").toInt());
        smtp->setConnectionType(smtp->getPort() != 25 ? SmtpClient::SslConnection : SmtpClient::TcpConnection);
        smtp->setAuthMethod(SmtpClient::AuthPlain);
        smtp->setUser(qApp->property("smtp_user").toString());
        smtp->setPassword(qApp->property("smtp_pass").toString());
        message->setSender(new EmailAddress(qApp->property("smtp_user").toString(), qApp->property("smtp_sender").toString()));
        QStringList list = qApp->property("smtp_recipients").toStringList();
        foreach (const QString &str, list) {
            message->addRecipient(new EmailAddress(str, str));
        }
        /*debug*/
        ((QSslSocket*)smtp->getSocket())->setPeerVerifyMode(QSslSocket::VerifyNone);
        if(smtp->connectToHost()) smtp->login();
        else{
            if(ui->detailed_checkBox->isChecked()){
                ui->data_textEdit->append(tr("%1 - Error connect to SMTP host: %2")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      .arg(smtp->getSocket()->errorString())
                                      );
            }
            this->mail_ready = true;
            delete(smtp);
            delete(message);
            delete(text);
            return;
        }
    }
    else if (qApp->property("smtp_type").toString() == "NTLM"){
        smtp->setHost(host);
        //smtp->setPort(465);
        smtp->setPort(qApp->property("smtp_port").toInt());
        //smtp->setConnectionType(smtp->getPort() != 25 ? SmtpClient::SslConnection : SmtpClient::TcpConnection);
        smtp->setAuthMethod(SmtpClient::AuthNtlm);
        smtp->setUser(qApp->property("smtp_user").toString());
        smtp->setPassword(qApp->property("smtp_pass").toString());
        message->setSender(new EmailAddress(qApp->property("smtp_user").toString(), qApp->property("smtp_sender").toString()));
        QStringList list = qApp->property("smtp_recipients").toStringList();
        foreach (const QString &str, list) {
            message->addRecipient(new EmailAddress(str, str));
        }
        //((QSslSocket*)smtp->getSocket())->setPeerVerifyMode(QSslSocket::VerifyNone);
        if(smtp->connectToHost()) smtp->login();
        else{
            if(ui->detailed_checkBox->isChecked()){
                ui->data_textEdit->append(tr("%1 - Error connect to SMTP host: %2")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      .arg(smtp->getSocket()->errorString())
                                      );
            }
            this->mail_ready = true;
            delete(smtp);
            delete(message);
            delete(text);
            return;
        }
    }

    message->setSubject(qApp->property("smtp_subject").toString());

    QString msg = QString("This is an alarm email message.\n%1 - measured temp is %2 %3C.")
                                   .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                   .arg(QString::number(this->currentTemperature, 'f', 2))
                                   .arg(ch);


    text->setText(msg);
    message->addPart(text);

    if(!smtp->sendMail(*message)){
        if(ui->detailed_checkBox->isChecked()){
            ui->data_textEdit->append(tr("%1 - Error sending message: %2")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      .arg(smtp->getSocket()->errorString())
                                      );
        }
    }
    else{
        if(ui->detailed_checkBox->isChecked()){
            ui->data_textEdit->append(tr("%1 - Alarm message was sent successfully")
                                      .arg(QDateTime::currentDateTime().toString("dd.MM.yyyy HH:mm"))
                                      );
        }
        this->last_msg = QDateTime::currentDateTime();
    }
    smtp->quit();
    delete(smtp);
    delete(message);
    delete(text);
    this->mail_ready = true;
}

bool MainWindow::loadUpdatePlugin()
{
    QDir pluginsDir(qApp->applicationDirPath());
    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if (plugin) {
            updmgr = qobject_cast<UpdMgrInterface *>(plugin);
            if (updmgr) return true;
        }
     }
     return false;
}

void MainWindow::setupGraph()
{
    QChar ch(0x00B0);
    QPen pen;
    pen.setColor(Qt::darkCyan);
    ui->plot->graph()->setLineStyle(QCPGraph::lsLine);
    ui->plot->graph()->setPen(pen);

    //ui->plot->xAxis->setLabel("time");
    ui->plot->yAxis->setLabel(QString("temperature (%1C)").arg(ch));

    ui->plot->yAxis->setAutoTicks(false);
    ui->plot->yAxis->setAutoTickLabels(false);

    ui->plot->yAxis->setRange(0 < qApp->property("min_temp").toInt() ? 0 : qApp->property("min_temp").toInt(),
                              50 > qApp->property("max_temp").toInt() ? 50 : qApp->property("max_temp").toInt());
    // configure bottom axis to show date and time instead of number:
    ui->plot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
    ui->plot->xAxis->setDateTimeFormat("HH:mm\ndd.MM.yy");
    // set a fixed tick-step to one tick per month:
    ui->plot->xAxis->setAutoTickStep(false);
    //ui->plot->xAxis->setTickStep(60); // in seconds
    ui->plot->xAxis->setSubTickCount(3);
    // set a more compact font size for bottom and left axis tick labels:
    ui->plot->xAxis->setTickLabelFont(QFont(QFont().family(), 6));
    ui->plot->yAxis->setTickLabelFont(QFont(QFont().family(), 6));

    ui->plot->yAxis->setTickVector(QVector<double>() << 0 << qApp->property("min_temp").toInt() << qApp->property("max_temp").toInt() << 50);
    ui->plot->yAxis->setTickVectorLabels(QVector<QString>() << QString("0") << tr("min") << tr("max") << QString("50"));

    ui->plot->xAxis->setTickStep(60*qApp->property("graphics_step").toInt());

    uint _time = QDateTime::currentDateTime().toTime_t();

    // make left and bottom axes transfer their ranges to right and top axes:
    connect(ui->plot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->xAxis2, SLOT(setRange(QCPRange)));
    connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange)));

    ui->plot->xAxis->setRange(_time-500, _time+100);

    ui->plot->setRangeDrag(Qt::Horizontal);
    ui->plot->setRangeZoom(Qt::Horizontal);
    ui->plot->setInteraction(QCustomPlot::iRangeZoom);

    ui->plot->setVisible(qApp->property("graphics_show").toBool());

    if(ui->plot->isVisible()) ui->plot->replot();
}

void MainWindow::updateProgram()
{
    if (this->loadUpdatePlugin()){
        connect(updmgr->updmgrObject(), SIGNAL(blockUserInput(bool)), this, SLOT(setDisabled(bool)));
        updmgr->checkForUpdate("serial temper",_STR_PRODUCT_VERSION);
    }
    else ui->data_textEdit->append(tr("Update Plugin not loaded!"));
}

void MainWindow::on_actionCheck_for_updates_triggered()
{
    this->updateProgram();
}

void MainWindow::on_actionThe_device_triggered()
{
    QDesktopServices::openUrl(QUrl("http://www.radiolocman.com/shem/schematics.html?di=45979"));
}

void MainWindow::on_actionCalibrate_triggered()
{
    if(!QFile::exists(QDir::home().absoluteFilePath("calibration.xls"))){
        if(!QFile::copy(":/unit/unit/calibration.xls", QDir::home().absoluteFilePath("calibration.xls"))) return;
        SetFileAttributes((LPCTSTR)QDir::home().absoluteFilePath("calibration.xls").utf16(), FILE_ATTRIBUTE_NORMAL);
    }
    QDesktopServices::openUrl(QUrl(QDir::home().absoluteFilePath("calibration.xls")));
}

void MainWindow::setupDatabase()
{
    //if(!qApp->property("save_history").toBool()) return;
    if(!QFile::exists(QDir::home().absoluteFilePath("SerialTemper.db"))){
        if(!QFile::copy(":/db/db/SerialTemper.db", QDir::home().absoluteFilePath("SerialTemper.db"))) return;
        SetFileAttributes((LPCTSTR)QDir::home().absoluteFilePath("SerialTemper.db").utf16(), FILE_ATTRIBUTE_NORMAL);
    }

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(QDir::home().absoluteFilePath("SerialTemper.db"));
    if(!db.open()){
        ui->data_textEdit->append(tr("Sql error: %1").arg(db.lastError().text()));
    }
}

void MainWindow::on_actionHistory_triggered()
{
    HistoryDialog* dlg = new HistoryDialog(this);
    dlg->exec();
    delete dlg;
}

void MainWindow::on_checkout_spinBox_valueChanged(int arg1)
{
    qApp->setProperty("check_interval", arg1);
}
